//stack.h
/********************************************************************************
*																				*
*	Author:			Jared Szechy												*
*	Assignment:		Assignment 7												*
*	Class:			CPS-151														*
*	Instructor:		V. Starkley													*
*	Due Date:		October 26													*
*																				*
*	Header file for templated Stack ADT .										*
*																				*
********************************************************************************/

#ifndef STACK_H
#define STACK_H

template <class ItemType>
struct NodeType;

template<class ItemType>
class StackType
{
public:
    StackType();
    //Class constructor.

    ~StackType();
    //Class destructor.

    StackType(const StackType<ItemType>& source);
    //Copy constructor

    StackType<ItemType> operator = (const StackType<ItemType>& source);
    //assignment operator

    void MakeEmpty();
    //pre:  none
	//post: Stack is empty.

    bool IsFull() const;
    //pre:  none
    //post: function returns true if stack is full, false if not full

    bool IsEmpty() const;
    //pre:  none
    //post: function returns true if stack is empty, false if not empty

    bool Push(ItemType item);
    //pre:  none
    //post: returns false if stack is full
	//		else item is added to the top of the stack and returns true

    bool Pop(ItemType& item);    
    //pre:  none
    //post: returns false if stack is empty
	//		else item is a copy of top element 
	//		top element is removed from stack and returns true

	bool Identical(StackType& s1);
	//pre:  none
	//post: returns true if calling object and s1 contain the exact same elements in the same order;
	//         else returns false

	StackType appendStack(StackType& aStack);
     //pre:  none
     //post:  returns a stack that contains all items from calling object and all items from aStack,
     //          items from calling object are at top of returned stack, followed by items from aStack,
     //          as shown in the example below;  aStack and calling object are unchanged

	void splitStack(StackType<ItemType>& stack1, StackType<ItemType>& stack2, ItemType splitValue);
    //pre:  item has a value; stack1 and stack2 are empty
    //post: stack1 contains all items (and only those items) from calling object < splitValue; 
    //         stack2 contains all items (and only those items) from calling object >= splitValue
    //          calling object is empty; 

private:
    NodeType<ItemType>* topPtr;
};

#include "stack.cpp"

#endif